﻿using ModbusRTULib;
using Sunny.UI;
using System;
using System.IO.Ports;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Forms;
using thinger.DataConvertLib;

namespace NModbus4Demo
{
    public partial class FrmModbusRTU : UIForm
    {
        public FrmModbusRTU()
        {
            InitializeComponent();
            InitParams();
        }

        private readonly ModbusRTU modbus = new ModbusRTU();
        private bool isConnect = false;

        /// <summary>
        /// 初始化数据
        /// </summary>
        private void InitParams()
        {
            // 获取端口号列表
            string[] ports = SerialPort.GetPortNames();
            if (ports.Length > 0)
            {
                this.CmbPort.Items.AddRange(ports);
                this.CmbPort.SelectedIndex = 1;
            }

            // 波特率
            this.CmbBaudRate.Items.AddRange(new string[] { "2400", "4800", "9600", "19200", "38400" });
            this.CmbBaudRate.SelectedIndex = 2;

            // 校验位
            this.CmbParity.DataSource = Enum.GetNames(typeof(Parity));

            // 数据位
            this.CmbDataBits.SelectedIndex = 1;

            // 停止位
            this.StopBits.DataSource = Enum.GetNames(typeof(StopBits));
            this.StopBits.SelectedIndex = 1;

            // 大小端
            this.CmbDataFormat.DataSource = Enum.GetNames(typeof(DataFormat));

            // 存储区
            this.CmbStoreArea.DataSource = Enum.GetNames(typeof(StoreArea));

            // 数据类型
            this.CmbDataType.DataSource = Enum.GetNames(typeof(DataType));

            // 动态修改ListView第二列的宽度
            this.LstInfo.Columns[1].Width = this.LstInfo.Width - this.LstInfo.Columns[0].Width - 4;
        }

        /// <summary>
        /// 点击连接按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnConnect_Click(object sender, EventArgs e)
        {
            if (isConnect)
            {
                AddLog(2, "ModbusRTU已经连接了，请不要再点我了！");
                return;
            }
            string portName = this.CmbPort.Text;
            int baudRate = int.Parse(this.CmbBaudRate.Text);
            Parity parity = (Parity)Enum.Parse(typeof(Parity), this.CmbParity.Text, true);
            int dataBits = int.Parse(this.CmbDataBits.Text);
            StopBits stopBits = (StopBits)Enum.Parse(typeof(StopBits), this.StopBits.Text, true);
            bool connectSuccess = modbus.Connect(portName, baudRate, parity, dataBits, stopBits);
            if (!connectSuccess)
            {
                AddLog(3, "ModbusRTU连接失败");
                return;
            }
            AddLog(0, "ModbusRTU连接成功！");
            isConnect = true;
        }

        /// <summary>
        /// 点击断开连接按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnDisConnect_Click(object sender, EventArgs e)
        {
            if (!isConnect)
            {
                AddLog(2, "ModbusRTU已经断开连接的了，请不要重复点我了！");
                return;
            }
            modbus.DisConnect();
            AddLog(0, "ModbusRTU断开连接成功");
            isConnect = false;
        }

        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="level"></param>
        /// <param name="message"></param>
        private void AddLog(int level, string message)
        {
            ListViewItem lst = new ListViewItem(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), level);
            lst.SubItems.Add(message);
            this.LstInfo.Items.Insert(0, lst);
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnRead_Click(object sender, EventArgs e)
        {
            if (!CommonVerify())
            {
                return;
            }
            byte slaveId = byte.Parse(this.TxtSlaveId.Text);
            ushort start = ushort.Parse(this.TxtStart.Text);
            ushort length = ushort.Parse(this.TxtLength.Text);
            DataType dataType = (DataType)Enum.Parse(typeof(DataType), this.CmbDataType.Text, true);
            StoreArea storeArea = (StoreArea)Enum.Parse(typeof(StoreArea), this.CmbStoreArea.Text, true);
            DataFormat dataFormat = (DataFormat)Enum.Parse(typeof(DataFormat), this.CmbDataFormat.Text, true);
            try
            {
                switch (dataType)
                {
                    case DataType.Bool:
                        ReadBool(storeArea, slaveId, start, length);
                        break;
                    case DataType.Byte:
                        Console.WriteLine("处理字节类型");
                        break;
                    case DataType.Short:
                        Console.WriteLine("处理有符号16位短整型");
                        break;
                    case DataType.UShort:
                        Console.WriteLine("处理无符号16位短整型");
                        break;
                    case DataType.Int:
                        Console.WriteLine("处理有符号32位整型");
                        break;
                    case DataType.UInt:
                        Console.WriteLine("处理无符号32位整型");
                        break;
                    case DataType.Float:
                        Console.WriteLine("处理32位单精度浮点数");
                        break;
                    case DataType.Double:
                        Console.WriteLine("处理64位双精度浮点数");
                        break;
                    case DataType.Long:
                        Console.WriteLine("处理有符号64位长整型");
                        break;
                    case DataType.ULong:
                        Console.WriteLine("处理无符号64位长整型");
                        break;
                    case DataType.String:
                        Console.WriteLine("处理字符串类型");
                        break;
                    case DataType.ByteArray:
                        Console.WriteLine("处理字节数组");
                        break;
                    case DataType.HexString:
                        Console.WriteLine("处理16进制字符串");
                        break;
                    default:
                        AddLog(3, "出现非法异常啦！");
                        break;
                }
                byte[] res = modbus.ReadOutputCoils(slaveId, start, length);
            }
            catch (Exception ex)
            {
                AddLog(3, "出现非法异常啦！：" + ex.Message);
            }
        }

        public void ReadBool(StoreArea storeArea, byte devId, ushort start, ushort length)
        {
            switch (storeArea)
            {

            }
        }

        /// <summary>
        /// 通用验证方法
        /// </summary>
        public bool CommonVerify()
        {
            if (!isConnect)
            {
                AddLog(3, "当前未连接！");
                return false;
            }

            string slaveId = this.TxtSlaveId.Text;
            if (!byte.TryParse(slaveId, out _))
            {
                AddLog(3, "站地址格式非法！");
                return false;
            }

            string start = this.TxtStart.Text;
            if (!ushort.TryParse(start, out _))
            {
                AddLog(3, "起始地址格式非法！");
                return false;
            }

            string length = this.TxtLength.Text;
            if (!ushort.TryParse(length, out _))
            {
                AddLog(3, "长度非法！");
                return false;
            }
            return true;
        }
    }
}
